package com.yax.main;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yax.util.RockUtil;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.io.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Logger;


/**
 * @Author: yax
 * @Date: 2021/1/28 15:46
 */
public class RockForm extends Application {
    private static Logger log = Logger.getLogger("RockForm");
    private static Stage stageNew=null;
    private Set<String> keySet=new HashSet<>();
    private Map<String,String> cookieMap=new HashMap<>();
    private static Map<String,String> rockUrl=new HashMap<>();
    private static final String version= "1.0.4";
    public static ExecutorService pool = Executors.newFixedThreadPool(1);
    static {
        rockUrl.put("sim","http://fpsim.cnzhonglunnet.com");
        rockUrl.put("pet","http://fppet.cnzhonglunnet.com");
        rockUrl.put("sit","http://fpsit.cnzhonglunnet.com");
        rockUrl.put("uat","http://fpuat.cnzhonglunnet.com");
        rockUrl.put("pre","http://fppre.cnzhonglunnet.com");
        rockUrl.put("vip","http://fpvip.cnzhonglunnet.com");
        rockUrl.put("prod","http://fp.cnzhonglunnet.com");
    }
    public static void main(String[] args) {
        log.info("入参:"+Arrays.asList(args));
        Thread thread =new Thread(()->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(args!=null&&args.length>0) {
                File file = new File(args[0]);
                boolean res=file.delete();
            }
        });
        thread.start();
        launch(args);
    }
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("磐石同步风控版本"+version);
        primaryStage.setResizable(true);
        primaryStage.setOnCloseRequest(event -> {
            pool.shutdownNow();
        });
        GridPane grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(25, 25, 25, 25));
        Text scenetitle = new Text("Welcome");
        scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));
        grid.add(scenetitle, 0, 0, 2, 1);


        String pwStr=readFileString(RockUtil.getExepath()+"rockconfig.json");
        JSONObject pwJsonTemp=new JSONObject();
        if(pwStr!=null&&!"".equals(pwStr)){
            try {
                pwJsonTemp = JSONObject.parseObject(pwStr);
            }catch (Exception e){
                e.printStackTrace();
            }
        }


        Label userName = new Label("用户名:");
        grid.add(userName, 0, 1);
        TextField userTextField = new TextField();

        String ln=pwJsonTemp.getString("loginname");
        String pwS=pwJsonTemp.getString("password");

        if(ln!=null&&!"".equals(ln)){
            userTextField.setText(ln.trim());
        }
        grid.add(userTextField, 1, 1,2,1);
        Label pw = new Label("密 码:");
        grid.add(pw, 0, 2);
        PasswordField pwBox = new PasswordField();
        if(pwS!=null&&!"".equals(pwS)){
            pwBox.setText(pwS.trim());
        }
        grid.add(pwBox, 1, 2,2,1);

        Label envLabelOriginal  = new Label("源环境:");
        grid.add(envLabelOriginal , 0, 3);
        ComboBox envAddressOriginal =new ComboBox(FXCollections.observableArrayList(Arrays.asList(new String[]{"pet","sim","sit","uat","pre","vip","prod"})));
        envAddressOriginal.setPrefWidth(400);
        envAddressOriginal.setEditable(true);
        envAddressOriginal.getSelectionModel().select(1);
        grid.add(envAddressOriginal, 1, 3,2,1);




        Label envLabel = new Label("目标环境:");
        grid.add(envLabel, 0, 4);
        ComboBox envAddress=new ComboBox(FXCollections.observableArrayList(Arrays.asList(new String[]{"pet","sim","sit","uat","pre","vip","prod"})));
        envAddress.setPrefWidth(400);
        envAddress.setEditable(true);
        envAddress.getSelectionModel().select(2);
        grid.add(envAddress, 1, 4,2,1);


        Label appLabel = new Label("应用编码:");
        grid.add(appLabel, 0, 5);
        ComboBox appAddress=new ComboBox();
        appAddress.setPrefWidth(400);
        appAddress.setEditable(true);
        appAddress.getSelectionModel().select(2);
        grid.add(appAddress, 1, 5,2,1);

        CheckBox cb = new CheckBox();

        ChangeListener<String> listener=  (observable, oldValue,newValue) -> {
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("rock返回");
            alert.setHeaderText(null);
            String env=envAddressOriginal.getValue().toString();
            String cookie=cookieMap.get(env);
            if(cookie==null) {
                Map<String, String> result = RockUtil.loginRock(rockUrl.get(env), userTextField.getText(), pwBox.getText());
                cookie = result.get("Cookie");
                String responseL=result.get("response");
                JSONObject responseTemp =JSONObject.parseObject(responseL);
                int successTemp = responseTemp.getInteger("success");
                if (successTemp == 0) {
                    alert.setContentText(responseTemp.getString("errorMsg"));
                    alert.showAndWait();
                    return;
                }
                if(successTemp==1){
                    cookieMap.put(env,cookie);
                    if(cb.isSelected()){
                        JSONObject pwJson=new JSONObject();
                        pwJson.put("loginname",userTextField.getText());
                        pwJson.put("password",pwBox.getText());
                        writeFileString(RockUtil.getExepath()+"rockconfig.json",pwJson.toJSONString());
                    }
                }
            }
            Set<String> appcodes = new HashSet<>();
            String appcode=newValue.toLowerCase();
            Map<String,String> param=new HashMap<>();
            param.put("appcode",appcode);
            param.put("flag","1");
            JSONObject jsonObject=RockUtil.getAppList(rockUrl.get(env),cookieMap.get(env),param);
            JSONArray jsonArray=jsonObject.getJSONObject("data").getJSONArray("list");
            jsonArray.forEach(obj->{
                JSONObject temp= (JSONObject) obj;
                appcodes.add(temp.getString("appcode"));
            });
            appAddress.setItems(FXCollections.observableArrayList(appcodes));
        };
        appAddress.getEditor().textProperty().addListener(listener);

        Label startLabel = new Label("开始时间:");
        grid.add(startLabel, 0, 6);

        DatePicker starttime = new DatePicker();
        starttime.setEditable(true);
        starttime.setPrefWidth(400);
        //选择监听
        starttime.valueProperty().addListener((observable, oldValue, newValue) -> {
        });
        grid.add(starttime, 1, 6,2,1);

        Label endLabel = new Label("结束时间:");
        grid.add(endLabel, 0, 7);

        DatePicker endtime = new DatePicker();
        endtime.setEditable(true);
        endtime.setPrefWidth(400);
        //选择监听
        endtime.valueProperty().addListener((observable, oldValue, newValue) -> {
        });

        grid.add(endtime, 1, 7,2,1);


        Label keyLabel = new Label("关键字:");
        grid.add(keyLabel, 0, 8);
        TextField keyField=new TextField();
        keyField.setPrefWidth(400);
        keyField.setEditable(true);
        grid.add(keyField, 1, 8,2,1);

        cb.setText("记住密码");
        cb.setSelected(true);
        grid.add(cb, 0, 9);

        Button btnImport = new Button("导入需要同步的风控key");
        HBox hbBtnImport = new HBox(10);
        hbBtnImport.setAlignment(Pos.BOTTOM_CENTER);
        hbBtnImport.getChildren().add(btnImport);
        grid.add(hbBtnImport, 1, 9);

        btnImport.setOnAction(e -> {
            // 创建新的stage
            if(stageNew==null) {
                stageNew = new Stage();
            }
            stageNew.setResizable(false);
            stageNew.setOnCloseRequest(event -> {
                stageNew.close();
                stageNew=null;
            });
            stageNew.setTitle("风控key");
            GridPane secondPane = new GridPane();
            Scene secondScene = new Scene(secondPane, 500, 500);
            TextArea textAreaTemp=new TextArea();
            textAreaTemp.setPrefSize(500,480);;
            textAreaTemp.setEditable(true);
            secondPane.add(textAreaTemp, 0, 0,5,5);
            Button btnimport = new Button("导入");
            btnimport.setPrefWidth(500);
            HBox hbBtnimport = new HBox(100);
            hbBtnimport.setAlignment(Pos.BOTTOM_CENTER);
            hbBtnimport.setPrefWidth(500);
            hbBtnimport.getChildren().add(btnimport);
            secondPane.add(hbBtnimport, 0, 9,5,1);
            btnimport.setOnAction(e1->{
                String source=textAreaTemp.getText().trim();
                try {
                    keySet.clear();
                    String attr_arr [];
                    if(source.contains(",")){
                         attr_arr  = source.split(",");
                    }else{
                        attr_arr  = source.split("[\\s\\n]");
                    }
                    for(String str:attr_arr){
                        if(str!=null&&!"".equals(str.trim())) {
                            keySet.add(str.trim());
                        }
                    }
                    textAreaTemp.clear();
                    stageNew.close();
                }catch (Exception ex){
                    ex.printStackTrace();
                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                    alert.setTitle("rock返回");
                    alert.setHeaderText(null);
                    alert.setContentText("导入失败 请去查看日志!!!");
                    alert.showAndWait();
                }
            });
            stageNew.setScene(secondScene);
            stageNew.show();
        });



        Button btn = new Button("同步风控");
        HBox hbBtn = new HBox(10);
        hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
        hbBtn.getChildren().add(btn);
        grid.add(hbBtn, 2, 9);

        Button clearbtn = new Button("清空应用编码");
        clearbtn.setPrefWidth(350);
        HBox clearhbBtn = new HBox(10);
        clearhbBtn.setAlignment(Pos.BOTTOM_CENTER);
        clearhbBtn.getChildren().add(clearbtn);
        grid.add(clearbtn, 0, 10,3,1);
        clearbtn.setOnAction(value->appAddress.setValue(""));

        //final Text actiontarget = new Text();
        //grid.add(actiontarget, 1, 12);
        btn.setOnAction((actionEvent)->{
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("rock返回");
            alert.setHeaderText(null);
            String envOriginal = envAddressOriginal.getValue().toString();
            String appcode=appAddress.getValue()==null?"":appAddress.getValue().toString();
            String start=starttime.getValue()==null?"":starttime.getValue().toString()+" 00:00:00";
            String end=endtime.getValue()==null?"":endtime.getValue().toString()+" 23:59:59";
            String keyword=keyField.getText()==null?"":keyField.getText();
            try {
                String cookie=cookieMap.get(envOriginal);
                if(cookie==null) {
                    Map<String, String> result = RockUtil.loginRock(rockUrl.get(envOriginal), userTextField.getText(), pwBox.getText());
                    cookie = result.get("Cookie");
                    String responseL=result.get("response");
                    JSONObject responseTemp =JSONObject.parseObject(responseL);
                    int successTemp = responseTemp.getInteger("success");
                    if (successTemp == 0) {
                        alert.setContentText(responseTemp.getString("errorMsg"));
                        alert.showAndWait();
                        return;
                    }
                    if(successTemp==1){
                        cookieMap.put(envOriginal,cookie);
                        if(cb.isSelected()){
                            JSONObject pwJson=new JSONObject();
                            pwJson.put("loginname",userTextField.getText());
                            pwJson.put("password",pwBox.getText());
                            writeFileString(RockUtil.getExepath()+"rockconfig.json",pwJson.toJSONString());
                        }
                    }
                }
                String env = envAddress.getValue().toString();
                String cookieTemp=cookieMap.get(env);
                if(cookieTemp==null) {
                    Map<String, String> resultTemp = RockUtil.loginRock(rockUrl.get(env), userTextField.getText(), pwBox.getText());
                     cookieTemp = resultTemp.get("Cookie");
                    cookieMap.put(env,cookieTemp);
                }
                if(!"".equals(appcode)||!"".equals(start)||!"".equals(end)||!"".equals(keyword)){
                    Map<String,String> param=new HashMap<>();
                    param.put("appcode",appcode);
                    param.put("starttime",start);
                    param.put("endtime",end);
                    param.put("keyword",keyword);
                    param.put("page","1");
                    param.put("pageSize","10000");
                    JSONObject jsonInfo= RockUtil.getRiskList(rockUrl.get(envOriginal),cookieMap.get(envOriginal),param);
                    JSONArray array=jsonInfo.getJSONObject("data").getJSONArray("list");
                    array.forEach(arr->{
                        JSONObject temp= (JSONObject) arr;
                        keySet.add(temp.getString("servicekey"));
                    });
                }
                Alert confirm = new Alert(Alert.AlertType.CONFIRMATION);
                confirm.setTitle("rock提醒");
                confirm.setHeaderText("同步servicekey集合");
                StringBuilder sb=new StringBuilder();
                int count=0;
                for(String key:keySet){
                    if(count>20){
                        sb.append("等等......");
                        break;
                    }
                    sb.append(key+"\r\n");
                    count++;
                }
                confirm.setContentText(sb.toString());
                Optional<ButtonType> buttonType = confirm.showAndWait();
                if (buttonType.get().getButtonData().equals(ButtonBar.ButtonData.OK_DONE)) {
                    Map<String,String> res=new HashMap<>();
                    keySet.forEach(servicekey -> {
                        try {
                            JSONObject jsonObject = RockUtil.getRiskDetailByKeyWord(rockUrl.get(envOriginal), cookieMap.get(envOriginal), servicekey);
                            log.info(servicekey + ":" + jsonObject.toJSONString());
                            JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("list");
                            if (jsonArray.size() == 0) {
                                res.put(servicekey, "servicekey不存在");
                                return;
                            }
                            if (jsonArray.size() > 1) {
                                res.put(servicekey, "servicekey不唯一");
                                return;
                            }
                            Map<String, String> riskDetail = (Map<String, String>) jsonArray.get(0);
                            JSONObject response = RockUtil.synRisk(rockUrl.get(env), cookieMap.get(env), riskDetail);
                            int success = response.getInteger("success");
                            if (success == 0) {
                                res.put(servicekey, response.getString("errorMsg"));
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            res.put(servicekey, "未知异常 请去查看错误日志");
                        }
                    });
                    StringBuilder sbs=new StringBuilder();
                    for(Map.Entry<String,String> entry:res.entrySet()){
                        sbs.append("servicekey:"+entry.getKey()+" errormsg:"+entry.getValue()+"\r\n");
                    }
                    alert.setContentText("同步风控失败原因:\r\n"+ sbs.toString() );
                    alert.showAndWait();
                } else { // 单击了取消按钮CANCEL_CLOSE
                }
                keySet.clear();
            }catch (Exception e){
                e.printStackTrace();
                StringWriter sw = new StringWriter();
                PrintWriter pwt = new PrintWriter(sw, true);
                e.printStackTrace(pwt);
                pwt.flush();
                sw.flush();
                alert.setContentText(sw.toString());
                alert.showAndWait();
            }

        });
        Scene scene = new Scene(grid, 400, 375);
        primaryStage.setScene(scene);
        primaryStage.show();

        pool.execute(()->{
            //检查更新
            checkVersion(primaryStage);
        });
    }

    public static String readFileString(String fileName) throws IOException {
        File file=new File(fileName);
        if(!file.exists()){
            return null;
        }
        try(BufferedReader in = new BufferedReader(new FileReader(file))) {
            StringBuilder sb = new StringBuilder();
            String str;
            while ((str = in.readLine()) != null) {
                sb.append(str);
            }
            return sb.toString();
        }
    }
    public static void writeFileString(String fileName, String str){
        try {
            File writeName = new File(fileName);
            writeName.createNewFile();
            try (FileWriter writer = new FileWriter(writeName, false);
                 BufferedWriter out = new BufferedWriter(writer)){
                out.write(str);
                out.newLine();   // 换行
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void checkVersion(Stage primaryStage){
        JSONObject versionInfo=RockUtil.getVersion();
        String newVersion=versionInfo.getString("version");
        String updateInfo=versionInfo.getString("info");
        if(!isNewVersion(version,newVersion)){
            Platform.runLater(() -> {
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                alert.setTitle("版本更新");
                alert.setHeaderText("当前版本号"+version+",最新版本号"+newVersion+",建议您更新程序");
                if(updateInfo!=null&&!"".equals(updateInfo)) {
                   alert.setContentText("本次更新内容:"+updateInfo+"\r\n"+"是否更新?");
                }else {
                    alert.setContentText("是否更新?");
                }
                Optional<ButtonType> result = alert.showAndWait();
                if (result.get() == ButtonType.OK){
                    Group root = new Group();
                    Scene scene = new Scene(root, 220, 50);
                    primaryStage.setScene(scene);
                    primaryStage.setTitle("下载进度");
                    final Label label = new Label();
                    label.setText("进度:");
                    final ProgressBar pb = new ProgressBar();
                    //pb.setProgress(values[i]);
                    final ProgressIndicator pin = new ProgressIndicator();
                    //pin.setProgress(values[i]);
                    final HBox hb  = new HBox();
                    hb.setSpacing(1);
                    hb.setAlignment(Pos.CENTER);
                    hb.getChildren().addAll(label, pb, pin);
                    final VBox vb = new VBox();
                    vb.setSpacing(1);
                    vb.getChildren().add(hb);
                    scene.setRoot(vb);
                    primaryStage.show();
                    RockUtil.downloadRock(pb,pin,version,newVersion,primaryStage);
                } else {
                    // ... user chose CANCEL or closed the dialog
                }
            });
        }

    }

    private boolean isNewVersion(String version,String newVersion){
        String[] versions=version.split("\\.");
        String[] newVersions=newVersion.split("\\.");
        int length=versions.length;
        int lengthV=newVersions.length;
        int minLength=Math.min(length,lengthV);
        for(int i=0;i<minLength;i++){
            int o=Integer.valueOf(versions[i]);
            int n=Integer.valueOf(newVersions[i]);
            if(o<n){
                return false;
            }
            if(o>n){
                return true;
            }
        }
        return length>=lengthV?true:false;
    }
}
